package jinyilw.swing.visuals.label;

import jinyilw.common.Operator;

import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicLabelUI;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

/**
 * @author Jinyi
 */
public class SwitchLabel extends JLabel // 开关图像标签
{
	private static final long serialVersionUID = 7860449399046540465L;
	private Icon openIcon;
	private Icon openOverIcon;
	private Icon closeIcon;
	private Icon closeOverIcon;
	private OverListener listener;
	private boolean opened = false;
	private int width, height;
	private volatile ArrayList<Operator<?>> offOperators;
	private volatile ArrayList<Operator<?>> onOperators;

	public SwitchLabel()
	{
		init();
	}

	public SwitchLabel(Icon oic, Icon ooic, Icon cic, Icon coic)
	{
		init();
		setSwitchIcon(oic, ooic, cic, coic);
	}

	private void init()
	{
		addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseClicked(MouseEvent e)
			{
				if (!isEnabled())
					return;
				if (opened)
				{
					close();
					if (onOperators != null)
						for (Operator<?> operator : onOperators)
							operator.run();
				} else
				{
					open();
					if (offOperators != null)
						for (Operator<?> operator : offOperators)
							operator.run();
				}
			}
		});
	}

	private synchronized void createOffOperators()
	{
		if (offOperators == null)
			offOperators = new ArrayList<>();
	}

	private synchronized void createOnOperators()
	{
		if (onOperators == null)
			onOperators = new ArrayList<>();
	}

	public void setSwitchIcon(Icon oic, Icon ooic, Icon cic, Icon coic)
	{
		if (oic != null)
			openIcon = oic;
		if (ooic != null)
			openOverIcon = ooic;
		if (cic != null)
		{
			closeIcon = cic;
			width = cic.getIconWidth();
			height = cic.getIconHeight();
			setSize(width, height);
			setIcon(cic);
		}
		if (coic != null)
			closeOverIcon = coic;
		if (listener == null)
		{
			listener = new OverListener();
			addMouseListener(listener);
		}
	}

	public void open()
	{
		if (opened)
			return;
		opened = true;
		if (openIcon != null)
			setIcon(openIcon);
	}

	public void close()
	{
		if (!opened)
			return;
		opened = false;
		if (closeIcon != null)
			setIcon(closeIcon);
	}

	public boolean isOpened()
	{
		return opened;
	}

	public void addOffOperator(Operator<?> operator)
	{
		if (offOperators == null)
			createOffOperators();
		offOperators.add(operator);
	}

	public void addOnOperator(Operator<?> operator)
	{
		if (onOperators == null)
			createOnOperators();
		onOperators.add(operator);
	}

	@Override
	public void updateUI()
	{
		setUI(new BasicLabelUI());
	}

	private class OverListener extends MouseAdapter
	{
		@Override
		public void mouseEntered(MouseEvent e)
		{
			if (opened && openOverIcon != null)
				setIcon(openOverIcon);
			if (!opened && closeOverIcon != null)
				setIcon(closeOverIcon);
		}

		@Override
		public void mouseExited(MouseEvent e)
		{
			if (opened && openIcon != null)
				setIcon(openIcon);
			if (!opened && closeIcon != null)
				setIcon(closeIcon);
		}
	}
}
